<template>
  <transition name="fade">
    <div class="all-city-list" v-show="handleVisible">
      <div class="current__city" @click="selectItem(currentCity)">
        当前定位城市: {{ handleCurrentCityName.cityName }}
      </div>
      <div class="city_list">
        <scroll ref="listview"
                :listen-scroll="true"
                :probeType="3"
                :data="data"
                @scroll="scroll">
          <ul>
            <li v-for="group in data" class="list-group" ref="listGroup">
              <h2 class="list-group-title">{{group.title}}</h2>
              <ul>
                <li @click="onSelectItem(item)" v-for="item in group.items" class="list-group-item">
                  <span class="name">{{ item.name }}</span>
                </li>
              </ul>
            </li>
          </ul>
          <div class="list-shortcut" @touchstart="onShortcutTouchStart" @touchmove.stop.prevent="onShortcutTouchMove">
            <ul>
              <li class="item" :class="{'current': index === currentIndex}" v-for="(item, index) in shortcutList" :data-index="index">
                {{item}}
              </li>
            </ul>
          </div>
          <div class="list-fixed" v-show="fixedTitle" ref="fixed">
            <div class="fixed-title">{{fixedTitle}}</div>
          </div>
        </scroll>
      </div>

    </div>
  </transition>

</template>
<script>
import { mapState, mapMutations, mapGetters } from 'vuex'
import { car } from '../../../data'
import * as util from 'utils/utils'
// 字母表每个元素的高度
const ANCHOR_HEIGHT = 18;
const TITLE_HEIGHT = 30;
export default {
  name: 'sl-city-list',
  data () {
    return {
      data: [],
      scrollY: -1,
      currentIndex: 0,
      diff: -1
    }
  },
  props: {
    visible: false,
    currentCity: {}
  },
  computed: {
    ...mapState([
      'userCarState'
    ]),
    ...mapGetters([
      'handleSearchCityNameText'
    ]),
    handleCurrentCityName () {
      let type = this.$route.params.address;
      let cityData = this.userCarState.callCarParams[type];
      if (type === 'endAddress' && cityData.cityName === '') {
        cityData = this.userCarState.callCarParams['startAddress'];
      }
      return cityData
    },
    handleVisible () {
      if (this.userCarState.searchAddress.isOpenCityName) {
        this.getAllCityNameData();
        return true
      }
      return false
    },
    shortcutList () {
      return this.data.map(item => {
        return item.title.substring(0, 1)
      })
    },
    fixedTitle () {
      if (this.scrollY > 0) {
        return ''
      }
      return this.data[this.currentIndex] ? this.data[this.currentIndex].title : ''
    }
  },
  created () {
    this.touch = {}
    this.listHeight = []
  },
  methods: {
    ...mapMutations([
      'SET_USER_CAR_START_ADDRESS',
      'SET_USER_CAR_END_ADDRESS',
      'SET_SHOW_TARGET_ADDRESS'
    ]),
    getAllCityNameData (cityName = '') {
      car.getCityList({
        cityName: cityName
      }).then((res) => {
        // 将获取到当所有城市列表重新排序成我们需要当格式
        if (res.data.code === 0) {
          this.data = util.sortCityList(res.data.data)
        } else {
          this.$vux.alert.show({
            title: res.msg,
            content: '请重新登陆'
          })
        }
      })
    },
    onSelectItem (item) {
      let address = {
        cityName: item.name,
        cityId: item.cityId
      };
      if (this.$route.params.address === 'startAddress') {
        this.SET_USER_CAR_START_ADDRESS(address);
      } else if (this.$route.params.address === 'endAddress') {
        this.SET_USER_CAR_END_ADDRESS(address);
      }
      this.SET_SHOW_TARGET_ADDRESS('isOpenHistoryAddress');
    },
    onShortcutTouchStart (e) {
      let anchorIndex = util.getData(e.target, 'index')
      let firstTouch = e.touches[0]
      this.touch.y1 = firstTouch.pageY
      this.touch.achortIndex = anchorIndex
      this._scrollTo(anchorIndex)
    },
    onShortcutTouchMove (e) {
      let firstTouch = e.touches[0]
      this.touch.y2 = firstTouch.pageY
      // 根据触摸事件和滑动事件获取滑动的距离/每个元素的高度 取整 = 当前滑过了多少个字母
      let delta = (this.touch.y2 - this.touch.y1) / ANCHOR_HEIGHT | 0
      let anchorIndex = parseInt(this.touch.achortIndex) + delta
      this._scrollTo(anchorIndex)
    },
    scroll (pos) {
      this.scrollY = pos.y
    },
    _scrollTo (index) {
      if (!index && index !== 0) {
        return
      }
      if (index < 0) {
        index = 0
      } else if (index > this.listHeight.length - 2) {
        index = this.listHeight.length - 2
      }
      // 参数1 目标dom 参数2 动画时间
      this.scrollY = -this.listHeight[index]
      this.$refs.listview.scrollToElement(this.$refs.listGroup[index], 0)
    },
    // 计算每组字母的高度
    _calculateHeight () {
      this.listHeight = []
      const list = this.$refs.listGroup
      if (!list) return false
      let height = 0
      this.listHeight.push(height)
      for (let i = 0; i < list.length; i++) {
        let item = list[i]
        height += item.clientHeight
        this.listHeight.push(height)
      }
    }
  },
  watch: {
    handleSearchCityNameText () {
      this.getAllCityNameData(this.handleSearchCityNameText);
    },
    data () {
      if (this.data.length > 0) {
        setTimeout(() => {
          this._calculateHeight()
        }, 20)
      }
    },
    visible () {
      if (this.visible) {
        // 如果城市列表显示 则重新计算列表内容
        setTimeout(() => {
          // 如果城列表为显示状态，则重新计算各个城市高度
          this.$refs.listview.refresh()
          this._calculateHeight()
        }, 20)
      }
    },
    // newY 页面卷入的值
    scrollY (newY) {
      const listHeight = this.listHeight
      for (let i = 0; i < listHeight.length; i++) {
        let height1 = listHeight[i]
        let height2 = listHeight[i + 1]
        if (-newY >= height1 && -newY < height2) {
          this.currentIndex = i
          this.diff = height2 + newY
          return
        }
      }
      this.currentIndex = 0
    },
    diff (newVal) {
      let fixedTop = (newVal > 0 && newVal < TITLE_HEIGHT) ? newVal - TITLE_HEIGHT : 0
      if (this.fixedTop === fixedTop) {
        return
      }
      this.fixedTop = fixedTop
      this.$refs.fixed.style.transform = `translate3d(0, ${fixedTop}px, 0)`
    }
  }
}
</script>
<style lang="stylus" type="text/stylus" scoped>
  @import "~assets/css/theme"
  .all-city-list
    width 100%
    position absolute
    top 4 * .61rem
    bottom 0
    .current__city
      position absolute
      top 0
      left 0
      right 0
      z-index 1
      padding 0 1 * .61rem
      background #fff
      display flex
      align-items center
      height 4 * .61rem
      margin-top 1 * .61rem
      font-size $sl_font_size_small
    .city_list
      position: absolute
      left 0
      right 0
      top 5 * .61rem
      bottom 0
      overflow: hidden
      background: $sl_theme_bg
      .list-group
        padding-bottom: 30px
        background #fff
        .list-group-title
          height: 30px
          line-height: 30px
          padding-left: 20px
          font-size $sl_font_size_16
          background $sl_theme_bg
        .list-group-item
          display: flex
          align-items: center
          padding: 20px 0 0 30px
          .avatar
            width: 50px
            height: 50px
            border-radius: 50%
          .name
            color: $sl_font_color_default
            font-size: $sl_font_size_14
      .list-shortcut
        position: absolute
        z-index: 30
        right: 5px
        top: 50%
        transform: translateY(-50%)
        width: 20px
        padding: 20px 0
        border-radius: 10px
        text-align: center

        font-family: Helvetica
        .item
          width 20px
          height 20px
          line-height: 20px
          color: $sl_font_color_default
          font-size: $sl_font_size_small
          &.current
            background $sl_place_to
            color #fff
            border-radius 50%
      .list-fixed
        position: absolute
        top: 0
        left: 0
        width: 100%
        .fixed-title
          height: 30px
          line-height: 30px
          padding-left: 20px
          font-size: $sl_font_size_16
          color: $sl_font_color_default
          background: $sl_theme_bg
      .loading-container
        position: absolute
        width: 100%
        top: 50%
        transform: translateY(-50%)
      .fade-enter-active, .fade-leave-active
        transition opacity .5s
      .fade-enter, .fade-leave-to
        opacity: 0
</style>
